package com.test;

import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;

public class PojoItem extends Item {

	
	public PojoItem(JsonKey key, Object obj) {
		super(key, obj);
		
	}
	
	protected void doReady(JsonWriter w){
		Class c = obj.getClass();
	
		if(!this.findAction(w, c)){
			return  ;
		}
		List<Item> items = makeItems(c,this.obj);
		if(this.childrenAction!=null){
			for(ChildrenAction a:this.childrenAction){
				if(!a.doIt(w, key, items)){
					return ;
				}
			}
		}
		
		
		Context ctx = w.ctx;
		RenderStack stack = ctx.getObjectStack();
		for(Object item:items){
			stack.push(item);
		}
		w.writeKey(key);
		w.enterObj();
		
		w.getCtx().scops.peek().addAllRuleNode(newRules);
	

		
	}
	
	protected void doRender(JsonWriter w){
		w.exitObj();
	}
	
	private List<Item> makeItems(Class c,Object obj){
		if(obj==null) return Collections.emptyList();
		List<Item> list = new LinkedList<Item>();
		Method[] ms = c.getMethods();
		for (Method m : ms) {
			if (isGetterMethod(m)) {
					Object value = value(obj,m);
					//if value!=null
					String name = getAttribute(m);
					JsonKey key = new JsonKey(name);
					Item item = ItemFactory.create(key, m.getReturnType(), value);
					item.setParent(this);
					list.add(item);
				}

			}
		return list;
		}
	
	public  boolean isGetterMethod(Method m){
		if(m.getDeclaringClass()==Object.class) return false;
		if(m.getName().startsWith("get")){
			if(m.getParameterTypes().length==0&&!Modifier.isStatic(m.getModifiers())){
				return true;
			}
		}else if(m.getName().startsWith("is")){
			if(m.getParameterTypes().length==0&&!Modifier.isStatic(m.getModifiers())){
				return true;
			}
		}
		return false;
	}
	
	public  String getAttribute(Method getter)
	{
		String methodName = getter.getName();
		StringBuilder mbuffer = new StringBuilder("");
		if(methodName.startsWith("is")){
			mbuffer.append(Character.toLowerCase(methodName.charAt(2)));
			mbuffer.append(methodName.substring(3));	
		}else{
			mbuffer.append(Character.toLowerCase(methodName.charAt(3)));
			mbuffer.append(methodName.substring(4));	
		}
		
		
		return mbuffer.toString();
	}
	
	public Object value(Object o,Method m){
		try {
			return m.invoke(o, new Object[]{});
		} catch (Exception e) {
			throw new RuntimeException(e);
		} 
	}
}
